package server.fsm;

import etc.SynchronizationParameters;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import lib.Base64;

public class DownloadingState extends GenericServerState {

	private String relativeFilePathAndName = null;

	private File destFile = null;

	private FileOutputStream outToFile = null;

	private Long lastModified = null;

	private long waitingBytes = 0;

	public DownloadingState( String file, Long size, Long lastModified ) throws FileNotFoundException {
		this.relativeFilePathAndName = file;
		this.destFile = new File( SynchronizationParameters.getLocalPath() + '\\' + file.replace('/', '\\') );
		this.destFile.getParentFile().mkdirs();

		this.outToFile = new FileOutputStream( destFile );
		this.lastModified = lastModified;
		this.waitingBytes = size;
	}

	@Override
	public String data( String base64EncodedDataString ) {

		try {
			if( (destFile != null) && (outToFile != null) ) {
				String retMsg = "";

				byte[] decodedData = Base64.decode( base64EncodedDataString );
				outToFile.write( decodedData );
				long bytesInPackage = (long)(decodedData.length);
				
				if( bytesInPackage == waitingBytes ) {

					retMsg = "<receive didFail='false' file='"+relativeFilePathAndName+"' />";
					try {
						outToFile.flush();
						outToFile.close();
					} catch (IOException ex) {}

					if( lastModified != null ) {
						destFile.setLastModified( lastModified );
					}
					
					destFile = null;
					getServerContext().setCurrentServerState( new AuthorizedState(), "Downloaded file '"+relativeFilePathAndName+"'." );

				}else if( bytesInPackage > waitingBytes ) {

					retMsg = "<receive didFail='true' file='"+relativeFilePathAndName+"' />";
					try {
						outToFile.flush();
						outToFile.close();
						destFile.delete();
					} catch (IOException ex) {}
					destFile = null;
					getServerContext().setCurrentServerState( new AuthorizedState(), "Could not download file '"+relativeFilePathAndName+"'." );

				}else if( bytesInPackage < waitingBytes ) {
					waitingBytes -= bytesInPackage;
					retMsg = "<waiting size='"+Long.toString( waitingBytes )+"' file='"+relativeFilePathAndName+"' />";
				}

				return retMsg;
			}
		} catch (IOException ex) {}

		return "<receive didFail='true' file='"+relativeFilePathAndName+"' />";
	}

	@Override
	public String logout() {
		try {
			outToFile.flush();
			outToFile.close();
		} catch (IOException ex) {}
		destFile = null;

		getServerContext().setCurrentServerState( new WaitingState(), "Client logged out, waiting for re-authorization." );
		return "<logout result='OK'>You have logged out from the server.</logout>";
	}
	
}
